/******************************************************************************
 *	@Author Raffaello Brondi
 *
 * 	@description Object used to make/handle http requests.
 *
 ******************************************************************************/

function Request() {
	if(window.XMLHttpRequest)// code for IE7+, Firefox, Chrome, Opera, Safari
		this.xmlhttp = new XMLHttpRequest();
	else// code for IE6, IE5
		this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

	this.xmlhttp.onreadystatechange = this.onStateChange.bind(this);
	//onStateChange will be executed in the scope of the Request object and not in the scope of XMLHttpRequest object.

	this.onSuccess = undefined;
	this.onFailure = undefined;
	this.url = undefined;
	this.aborted = false;
}

Request.prototype = {
	constructor : Request,

	/**************************************************************************
	 *						GETTERS & SETTERS
	 *************************************************************************/
	setOnSuccess : function(onSuccess) {
		this.onSuccess = onSuccess;
	},
	setOnFailure : function(onFailure) {
		this.onFailure = onFailure;
	},
	getOnSuccess : function(onSuccess) {
		return this.onSuccess;
	},
	getOnFailure : function(onFailure) {
		return this.onFailure;
	},
	/**************************************************************************
	 *							METHODS
	 *************************************************************************/

	asyncGetRequest : function(url) {
		this.url = url;
		this.xmlhttp.open("GET", url, true);
		this.xmlhttp.send();
	},

	asyncPutRequest : function(url, params) {
		this.url = url;
		this.xmlhttp.open("PUT", url, true);
		if(params != undefined){
			//Send the proper header information along with the request
			this.xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			this.xmlhttp.setRequestHeader("Content-length", params.length);
			this.xmlhttp.setRequestHeader("Connection", "close");

			this.xmlhttp.send(params);
		}
		else
			this.xmlhttp.send();
	},

	asyncPostRequest : function(url, params) {
		this.url = url;
		this.xmlhttp.open("POST", url, true);

		//Send the proper header information along with the request
		this.xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		this.xmlhttp.setRequestHeader("Content-length", params.length);
		this.xmlhttp.setRequestHeader("Connection", "close");

		this.xmlhttp.send(params);
	},

	onStateChange : function(response) {
		if(this.aborted)
			return;

		if(!response)
			return;

//		log("response ready state : " + response.target.readyState);
		if(response.target.readyState == 4) {
			var result = undefined;
			
			if(this.xmlhttp.getResponseHeader("Content-Type") == "application/json"){
				result = jQuery.parseJSON(response.target.response);
			}
				
			if(response.target.status == 200) {
				if(this.onSuccess){
					this.onSuccess(result);
				}
			} else { 
				if(this.onFailure){
					this.onFailure(result);
				}
			}
		}
	},

	abort : function(){
		log('Aborting request : ' + this.url);
		this.xmlhttp.abort();
		this.aborted = true;
	}
}
